package com.gavin.plugin.database.ext;

import java.util.concurrent.atomic.AtomicBoolean;

//import org.apache.log4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gavin.model.Result;

public abstract class ThreadExt {
	static Logger logger = LoggerFactory.getLogger(ThreadExt.class);

	private InnerThread intThread;
	protected AtomicBoolean abCanExit;
	private String strName;
	
	public ThreadExt() {
		// 在此处初始化所有非静态的内部protected和private对象，所有引用对象的
		// 内部变量初始化为null，比如：
		// m_strName ="";
		// m_dataEngine =null;
		// m_slSet =new SortedList();
	}

	/**
	 * ------------------------------
	 * 内部线程
	 * ------------------------------
	 * @author wdm（l311576@sina.com）  @date 2018年7月27日
	 * @version 1.0
	 */
	class InnerThread extends Thread {
		private AtomicBoolean abIsRunning = new AtomicBoolean();

		public boolean isRunning() {
			return abIsRunning.get();
		}

		protected ThreadExt thread;

		public void setThread(ThreadExt thread) {
			this.thread = thread;
		}

		public void run() {
			abIsRunning.set(true);
			try {
				while (true) {
					try {
						thread.threadProc();
						break;
					} catch (Exception e) {
						logger.error("JThread uncatched exception:" + this.getName() + "," + e.getMessage(), e);
						ThreadExt.sleep(1000);
						logger.warn("JThread " + this.getName() + " restarted.");
						continue;
					}
				}
			} finally {
				abIsRunning.set(false);
			}
		}

		public InnerThread() {
			thread = null;
			abIsRunning.set(false);
		}
	}

	public boolean isRunning() {
		if (this.intThread == null) {
			return false;
		}
		return this.intThread.isRunning();
	}

	public String getName() {
		if (this.intThread == null) {
			return this.strName;
		} else {
			return this.intThread.getName();
		}
	}

	public void setName(String strName) {
		if (this.intThread != null) {
			this.intThread.setName(strName);
		}
		this.strName = strName;
	}

	/**
	 * 当前线程休眠指定的毫秒数
	 */
	public final static void sleep(int millisecond) {
		try {
			Thread.sleep(millisecond);
		} catch (Exception e) {
		}
	}

	/**
	 * 启动线程
	 */
	public synchronized Result start() {
		if (this.isRunning() == true) {
			return Result.OK;
		}
		this.abCanExit = new AtomicBoolean();
		this.abCanExit.set(false);
		this.intThread = new InnerThread();
		if (this.strName == null) {
			this.intThread.setName("JThread" + this.hashCode());
		} else {
			this.intThread.setName(this.strName);
		}
		this.intThread.setThread(this);
		while (this.isRunning() == false) {
			try {
				intThread.start();
				break;
			} catch (Exception e) {
				sleep(10);
			}
		}
		return Result.OK;
	}

	/**
	 * 停止线程
	 */
	public synchronized void stop() {
		if (this.intThread == null) {
			return;
		}
		stopProc();
		while (true) {
			try {
				this.intThread.join();
				break;
			} catch (Exception e) {
			}
		}
		this.intThread = null;
	}

	public synchronized void toStop() {
		if (this.isRunning() == false) {
			return;
		}
		stopProc();
	}

	protected void stopProc() {
		this.abCanExit.set(true);
	}

	protected abstract void threadProc();
}
